/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "3D控制手柄.h"
#include "物体编辑/物体编辑.h"
#include <几何图形/图形相交.h>
#include <matXX.h>

#include "框架/视口元素.h"




static std::vector<S_物体*> g要变换的物体;
static std::vector<Mat44f>	g要变换的物体暂存矩阵;
static std::vector<Mat44f>	g要旋转的物体暂存矩阵;
static std::vector<vec3>	g要变换的物体暂存全局坐标;
static std::vector<vec3>	g要变换的物体暂存位置;
static std::vector<vec3>	g要变换的物体暂存旋转;
static std::vector<vec3>	g要变换的物体暂存缩放;
static std::vector<vec4>	g要变换的物体暂存quat;
static float32				g记录初始步进 = 0;
static vec3					g手柄初始位置 = {};
static vec2					g投影比例 = { 1,1 };


S_Bounding f_get移动控制手柄手柄最大长度(E_轴向 轴向) {
	uint32 vertOffset = 0;
	switch (轴向) {
	case E_轴向::e_X: vertOffset = S_框架::g_变换手柄方向线[0]->m_PickIndirect.firstVertex; break;
	case E_轴向::e_Y: vertOffset = S_框架::g_变换手柄方向线[1]->m_PickIndirect.firstVertex; break;
	case E_轴向::e_Z: vertOffset = S_框架::g_变换手柄方向线[2]->m_PickIndirect.firstVertex; break;
	default:
		return {};
	}

	S_Bounding coord;
	coord.min = f_surface_get全局偏移顶点坐标((S_Mesh*)S_框架::g_变换手柄->m_Data[0], S_框架::g_变换手柄->f_get矩阵2(), vertOffset);
	coord.max = f_surface_get全局偏移顶点坐标((S_Mesh*)S_框架::g_变换手柄->m_Data[0], S_框架::g_变换手柄->f_get矩阵2(), vertOffset + 1);

	return coord;
}

E_轴向 f_get控制手柄轴向(uint8 拾取到的线ID) {
	switch (拾取到的线ID) {
	case 0: return E_轴向::e_X;
	case 1: return E_轴向::e_Y;
	case 2: return E_轴向::e_Z;
	default:
		return E_轴向::e_None轴向;
	}
	return E_轴向::e_XYZ;
}

E_轴向 f_拾取手柄轴(const vec3& sr, const vec3& er, float32 相交距离) {
	S_Mesh* 手柄网格 = (S_Mesh*)(S_框架::g_变换手柄->m_Data[0]);
	auto* e = f_prop_Bool_1D(S_框架::g_变换类型开关);


	float32 拾取距离 = vec_len(S_节点数据::g_当前操作视口相机->f_get位置() - S_框架::g_变换手柄->f_get位置()) * 0.025;
	S_线拾取 线拾取 = { 100000000 , 100000000, -1 };
	Mat44f mat[2] = {S_框架::g_变换手柄->f_get矩阵2(), S_节点数据::g_当前操作视口相机->f_get矩阵2()};

	float32 面拾取距离 = 100000000;
	int32   轴ID = -1;
	int32   面拾轴ID = -1;

	//S_框架::g_变换轴 = E_轴向::e_None轴向;
	S_框架::g_变换方式 = E_变换::e_变换_None;
	if (e[0].m_Value) {
		for (uint32 i = 0; i < 3; ++i) {
			auto 轴线 = S_框架::g_变换手柄方向线[i];
			uvec2 indirect = {轴线->m_PickIndirect.firstVertex, 轴线->m_PickIndirect.vertexCount};
			线拾取 = f_surface_线段相交(手柄网格, mat, S_框架::G变换手柄方向线绘制属性, indirect, sr, er, 拾取距离);

			if (线拾取.相交距离 < 拾取距离) {
				拾取距离 = 线拾取.相交距离;
				轴ID = i;

				S_框架::g_变换方式	= E_变换::e_移动;
			}

			auto 箭头 = S_框架::g_变换手柄移动箭头[i];
			indirect = {箭头->m_PickIndirect.firstVertex, 箭头->m_PickIndirect.vertexCount};
			S_面拾取 面拾取 = f_surface_射线面相交(手柄网格, mat, S_框架::G变换手柄端箭头绘制属性[i], indirect, sr, er);
			if (面拾取.相交距离 < 面拾取距离) {
				面拾取距离 = 面拾取.相交距离;
				面拾轴ID = i;

				S_框架::g_变换方式	= E_变换::e_移动;
			}
		}
	}

	if (e[1].m_Value) {
		for (uint32 i = 0; i < 3; ++i) {
			auto 圆圈线 = S_框架::g_变换手柄圆圈线[i];
			uvec2 indirect = {圆圈线->m_PickIndirect.firstVertex, 圆圈线->m_PickIndirect.vertexCount};
			线拾取 = f_surface_线段相交(手柄网格, mat, S_框架::G变换手柄方向线绘制属性, indirect, sr, er, 拾取距离);

			if (线拾取.相交距离 < 拾取距离) {
				拾取距离 = 线拾取.相交距离;
				轴ID = i;

				S_框架::g_变换方式	= E_变换::e_旋转;
			}
		}
	}

	if (e[2].m_Value) {
		for (uint32 i = 0; i < 3; ++i) {
			auto 轴线 = S_框架::g_变换手柄方向线[i];
			uvec2 indirect = {轴线->m_PickIndirect.firstVertex, 轴线->m_PickIndirect.vertexCount};
			线拾取 = f_surface_线段相交(手柄网格, mat, S_框架::G变换手柄方向线绘制属性, indirect, sr, er, 拾取距离);

			if (线拾取.相交距离 < 拾取距离) {
				拾取距离 = 线拾取.相交距离;
				轴ID = i;

				S_框架::g_变换方式	= E_变换::e_缩放;
			}


			auto 端点 = S_框架::g_变换手柄缩放端点[i];
			indirect = {端点->m_PickIndirect.firstVertex, 端点->m_PickIndirect.vertexCount};
			S_面拾取 面拾取 = f_surface_射线面相交(手柄网格, mat, S_框架::G变换手柄端箭头绘制属性[i], indirect, sr, er);
			if (面拾取.相交距离 < 面拾取距离) {
				面拾取距离 = 面拾取.相交距离;
				面拾轴ID = i;

				S_框架::g_变换方式	= E_变换::e_缩放;
			}

		}
	}


	int32 轴 = 面拾轴ID;
	if (轴 < 0) {
		轴 = 轴ID;
	}
	//else {
		//S_框架::g_变换方式 = E_变换::e_变换_None;
	//}

	
	
	
	S_Mesh* 手柄面网格 = (S_Mesh*)(S_框架::g_变换手柄->m_Data[1]);
	switch (S_框架::g_变换方式) {
	case E_变换::e_移动: {
		for (uint32 i = 0; i < 3; ++i) {
			if (i != 轴) {
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
				//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄移动箭头[i]->m_ID, S_框架::G变换手柄端箭头绘制属性[i]);
				f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄方向线[i]->m_ID);
				f_mesh_set间接绘制网格属性(手柄面网格, S_框架::G变换手柄端箭头绘制属性[i], S_框架::g_变换手柄移动箭头[i]->m_ID);
			}
			else {
				auto 线属性 = S_框架::G变换手柄方向线绘制属性;
				线属性.m_Intensity = 2;
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, 线属性);
				f_mesh_set间接绘制网格属性(手柄网格, 线属性, S_框架::g_变换手柄方向线[i]->m_ID);
				线属性 = S_框架::G变换手柄端箭头绘制属性[i];
				线属性.m_Intensity = 2;
				//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄移动箭头[i]->m_ID, 线属性);
				f_mesh_set间接绘制网格属性(手柄面网格, 线属性, S_框架::g_变换手柄移动箭头[i]->m_ID);
			}
		}
		break;
	}
	case E_变换::e_旋转: {
		for (uint32 i = 0; i < 3; ++i) {
			if (i != 轴) {
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄圆圈线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
				f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄圆圈线[i]->m_ID);
			}
			else {
				auto 线属性 = S_框架::G变换手柄方向线绘制属性;
				线属性.m_Intensity = 2;
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄圆圈线[i]->m_ID, 线属性);
				f_mesh_set间接绘制网格属性(手柄网格, 线属性, S_框架::g_变换手柄圆圈线[i]->m_ID);
			}
		}
		break;
	}
	case E_变换::e_缩放: {
		for (uint32 i = 0; i < 3; ++i) {
			if (i != 轴) {
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
				//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄缩放端点[i]->m_ID, S_框架::G变换手柄端箭头绘制属性[i]);
				f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄方向线[i]->m_ID);
				f_mesh_set间接绘制网格属性(手柄面网格, S_框架::G变换手柄端箭头绘制属性[i], S_框架::g_变换手柄缩放端点[i]->m_ID);
			}
			else {
				auto 线属性 = S_框架::G变换手柄方向线绘制属性;
				线属性.m_Intensity = 2;
				//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, 线属性);
				f_mesh_set间接绘制网格属性(手柄网格, 线属性, S_框架::g_变换手柄方向线[i]->m_ID);
				线属性 = S_框架::G变换手柄端箭头绘制属性[i];
				线属性.m_Intensity = 2;
				//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄缩放端点[i]->m_ID, 线属性);
				f_mesh_set间接绘制网格属性(手柄面网格, 线属性, S_框架::g_变换手柄缩放端点[i]->m_ID);
			}
		}
		break;
	}
	default:
		for (uint32 i = 0; i < 3; ++i) {
			//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
			//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄移动箭头[i]->m_ID, S_框架::G变换手柄端箭头绘制属性[i]);
			f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄方向线[i]->m_ID);
			f_mesh_set间接绘制网格属性(手柄面网格, S_框架::G变换手柄端箭头绘制属性[i], S_框架::g_变换手柄移动箭头[i]->m_ID);

			//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄圆圈线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
			f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄圆圈线[i]->m_ID);

			//f_material_set线属性(S_框架::g_手柄线材质, S_框架::g_变换手柄方向线[i]->m_ID, S_框架::G变换手柄方向线绘制属性);
			//f_material_set线属性(S_框架::g_手柄面材质, S_框架::g_变换手柄缩放端点[i]->m_ID, S_框架::G变换手柄端箭头绘制属性[i]);
			f_mesh_set间接绘制网格属性(手柄网格, S_框架::G变换手柄方向线绘制属性, S_框架::g_变换手柄方向线[i]->m_ID);
			f_mesh_set间接绘制网格属性(手柄面网格, S_框架::G变换手柄端箭头绘制属性[i], S_框架::g_变换手柄缩放端点[i]->m_ID);
		}
		break;
	}
	

	if (轴 >= 0) {
		switch (轴) {
		case 0:
			return E_轴向::e_X;

		case 1:
			return E_轴向::e_Y;

		case 2:
			return E_轴向::e_Z;
		default:
			break;
		}
	}
	return E_轴向::e_None轴向;
	
	std::cout<<"拾取距离:"<<轴ID << " " << 面拾轴ID << std::endl;

}







void f_控制手柄_准备移动物体() {
	//auto obsNode = f_global_get激活可视物体节点();
	g要变换的物体.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体暂存矩阵.clear();
	g要变换的物体暂存全局坐标.clear();

	g手柄初始位置 = S_框架::g_变换手柄->f_get位置();


	if (f_prop_Bool(S_节点数据状态::g_打开编辑模式)) {
		for (auto 拾取物体 : f_global_get编辑拾取物体()) {
			g要变换的物体.push_back(拾取物体.物体);
		}
	}
	else {
		for (auto* ob : S_节点数据::g_选中激活物体) {
			g要变换的物体.push_back(ob);
		}
	}

	for (auto* ob : g要变换的物体) {
		g要变换的物体暂存位置.push_back(ob->f_get位置());
		if (ob->m_父物体) {
			//Mat44f mat = f_ob_get父对象变换矩阵(ob->m_父物体, ob->m_父物体->m_实例ID);
			Mat44f mat = f_ob_get父对象变换矩阵(ob->m_父物体, 0);
			g要变换的物体暂存矩阵.push_back(mat);
		}
		else {
			g要变换的物体暂存矩阵.push_back(f_mat44_identity());
		}
		
		//g要变换的物体暂存矩阵.push_back((mat));
		g要变换的物体暂存全局坐标.push_back(f_ob_get全局坐标(ob, ob->m_实例ID));
	}

	f_OE_准备变换(g要变换的物体, 1 << E_变换::e_移动);
}

void f_控制手柄_移动物体(const vec3& 手柄要移动到是位置) {
	S_框架::g_变换手柄->f_set位置(手柄要移动到是位置, 0);

	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* g = g要变换的物体暂存全局坐标.data();
	auto* mat = g要变换的物体暂存矩阵.data();
	for (int32 i = 0; i < num; ++i) {
		Mat44f m;
		if (ob[i]->m_父物体) {
			//m = f_ob_get父对象变换矩阵(ob[i]->m_父物体, ob[i]->m_父物体->m_实例ID);
			m = f_ob_get父对象变换矩阵(ob[i]->m_父物体, 0);
		}
		else {
			m = f_mat44_identity();
		}

		m.m30 = 0;
		m.m31 = 0;
		m.m32 = 0;
		m.m33 = 1;
		vec3 缩放 = { vec_len(m * vec3{ 1, 0, 0 }), vec_len(m * vec3{ 0, 1, 0 }), vec_len(m * vec3{ 0, 0, 1 }) };
		
		m = f_mat44_Inverse(m);
		mat44_normalize(m);
		
		vec3 移动矢量 = (手柄要移动到是位置 + (g[i] - g手柄初始位置)) - g[i];
		移动矢量 = m * 移动矢量 / 缩放;

		ob[i]->f_set位置(v[i] + 移动矢量, 0);
	}
	
	f_OE_移动后更新(g要变换的物体);
	
}

void f_控制手柄_完成移动物体(S_摄像机* camera) {
	//f_控制手柄_移动到选中物体中心(g要变换的物体);
	f_camera_set偏移视点(camera, S_框架::g_变换手柄->f_get位置());

	g要变换的物体.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体暂存矩阵.clear();
	g要变换的物体暂存全局坐标.clear();

	f_global_变换手柄到物体中心();
	f_projectFile_设置文件保存状态(false);
}

void f_控制手柄_取消移动物体(S_摄像机* camera) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();

	for (int32 i = 0; i < num; ++i) {
		ob[i]->f_set位置(v[i], 0);
	}
	S_框架::g_变换手柄->f_set位置(g手柄初始位置, 0);

	f_OE_移动后更新(g要变换的物体);

	f_控制手柄_完成移动物体(camera);
}





void f_控制手柄_准备旋转物体(const vec2& 鼠标局部位置, const S_Rect2Df& rect, S_摄像机* camera) {
	f_控制手柄_完成旋转物体();


	g手柄初始位置 = S_框架::g_变换手柄->f_get位置();
	vec2 coord = f_Project空间坐标转屏幕(camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, g手柄初始位置, rect);

	vec2 鼠标移动方向 = (鼠标局部位置 - coord);
	g记录初始步进 = f_graph_两向量夹角弧度(vec_normalize2(鼠标移动方向), {1,0});
	if (鼠标移动方向.y < 0) g记录初始步进 = M_PI - g记录初始步进 + M_PI;


	if (f_prop_Bool(S_节点数据状态::g_打开编辑模式)) {
		for (auto 拾取物体 : f_global_get编辑拾取物体()) {
			g要变换的物体.push_back(拾取物体.物体);
		}
	}
	else {
		for (auto* ob : S_节点数据::g_选中激活物体) {
			g要变换的物体.push_back(ob);
		}
	}


	for (auto* ob : g要变换的物体) {
		g要变换的物体暂存位置.push_back(ob->f_get位置());
		g要变换的物体暂存全局坐标.push_back(f_ob_get全局坐标(ob, ob->m_实例ID));

		//Mat44f mat = f_mat44_Inverse(f_ob_get父对象变换矩阵(ob, ob->m_实例ID, 0, false));
		Mat44f mat = f_mat44_Inverse(f_ob_get父对象变换矩阵(ob, 0, false));
		mat.m30 = 0;
		mat.m31 = 0;
		mat.m32 = 0;
		mat.m33 = 1;
		g要变换的物体暂存矩阵.push_back(mat);

		//mat = f_ob_get父对象变换矩阵(ob, ob->m_实例ID, 0, true);
		mat = f_ob_get父对象变换矩阵(ob, 0, true);
		mat44_normalize(mat);
		mat = f_mat44_Inverse(mat);
		mat.m30 = 0;
		mat.m31 = 0;
		mat.m32 = 0;
		mat.m33 = 1;
		
		g要旋转的物体暂存矩阵.push_back(mat);

		g要变换的物体暂存旋转.push_back(ob->f_get旋转());

		auto q = f_graph_欧拉角转四元数(ob->f_get旋转());
		g要变换的物体暂存quat.push_back(q);
	}


	f_OE_准备变换(g要变换的物体, 1 << E_变换::e_旋转);
}

void f_控制手柄_视线旋转物体(vec3 旋转向量, float32 弧度, float32 方向, S_摄像机* camera) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	//auto* r = g要变换的物体暂存旋转.data();
	auto* q = g要变换的物体暂存quat.data();
	auto* 物体全局坐标 = g要变换的物体暂存全局坐标.data();
	auto* mat = g要变换的物体暂存矩阵.data();
	auto* 旋转矩阵 = g要旋转的物体暂存矩阵.data();

	//vec3 手柄位置 = S_Core::g_变换手柄->f_get位置();
	for (int32 i = 0; i < num; ++i) {
		//视线向量 = 旋转向量;
		if (camera->m_投影模式 == E_投影模式::e_正交) {
			方向 *= -1;
		}

		vec4 rot_q = f_graph_从轴向角度计算四元数(旋转向量, (弧度 - g记录初始步进) * 方向);
		vec3 移动矢量 = (f_graph_quat变换坐标(rot_q, 物体全局坐标[i] - g手柄初始位置));
		移动矢量 = mat[i] * 移动矢量;
		ob[i]->f_set位置(v[i] + ((g手柄初始位置 + 移动矢量) - 物体全局坐标[i]), 0);
		
		
		//vec3 视线向量 = 旋转向量;
		vec3 视线向量 = vec_normalize2(旋转矩阵[i] * 旋转向量);
		//vec3 视线向量A = vec_normalize2(旋转矩阵[i] * (旋转向量 * 2));
		vec4 qa = f_graph_从轴向角度计算四元数(视线向量, (-(弧度 - g记录初始步进)) * 方向);
		vec4 newQuat = f_graph_quat相乘(q[i], qa);
		//vec4 newQuat = f_graph_quat旋转(qa, q[i]);
		ob[i]->f_set旋转(f_graph_四元数转欧拉角(newQuat), 0);
	}

	f_OE_旋转后更新(g要变换的物体);
	
}

void f_控制手柄_局部旋转物体(E_轴向 轴向, float32 角度) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* r = g要变换的物体暂存旋转.data();

	for (int32 i = 0; i < num; ++i) {
		switch (轴向) {
		case E_轴向::e_X: ob[i]->m_变换.rotation.x = r[i].x + M_弧度转角度(角度); break;
		case E_轴向::e_Y: ob[i]->m_变换.rotation.y = r[i].y + M_弧度转角度(角度); break;
		case E_轴向::e_Z: ob[i]->m_变换.rotation.z = r[i].z + M_弧度转角度(角度); break;
		}
	}


	f_OE_旋转后更新(g要变换的物体);
}

void f_控制手柄_完成旋转物体() {
	g要变换的物体暂存全局坐标.clear();
	g要变换的物体暂存矩阵.clear();
	g要旋转的物体暂存矩阵.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体暂存旋转.clear();
	g要变换的物体暂存quat.clear();
	g要变换的物体.clear();

	f_global_变换手柄到物体中心();
	f_projectFile_设置文件保存状态(false);
}

void f_控制手柄_取消旋转物体() {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* r = g要变换的物体暂存旋转.data();

	for (int32 i = 0; i < num; ++i) {
		ob[i]->f_set位置(v[i], 0);
		ob[i]->f_set旋转(r[i], 0);
	}

	f_控制手柄_完成旋转物体();
}







void f_控制手柄_准备缩放物体(const vec2& 鼠标局部位置, const S_Rect2Df& rect, S_摄像机* camera) {
	vec3 手柄位置 = S_框架::g_变换手柄->f_get位置();
	vec2 coord = f_Project空间坐标转屏幕(camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, 手柄位置, rect);
	g记录初始步进 = vec_len(鼠标局部位置 - coord);

	g投影比例 = f_ui_get空间投影比例(rect, camera->m_相机投影, camera->m_视点距离);



	g要变换的物体暂存缩放.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体.clear();

	if (f_prop_Bool(S_节点数据状态::g_打开编辑模式)) {
		auto obsNode = f_global_get激活可视物体节点();
		for (auto* node : obsNode) {
			auto* ob = node->f_get虚拟体();
			if (ob) {
				g要变换的物体.push_back(ob);
				g要变换的物体暂存位置.push_back(ob->f_get位置());
				g要变换的物体暂存缩放.push_back(ob->f_get缩放());
			}
		}
	}
	else {
		for (auto& ob : S_节点数据::g_选中激活物体) {
			g要变换的物体.push_back(ob);
			g要变换的物体暂存位置.push_back(ob->f_get位置());
			g要变换的物体暂存缩放.push_back(ob->f_get缩放());
		}
	}

	f_OE_准备变换(g要变换的物体, 1 << E_变换::e_缩放);
}

void f_控制手柄_视线缩放物体(vec3 旋转向量, float32 步进) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();
	auto* g = g要变换的物体暂存全局坐标.data();

	vec3 手柄位置 = S_框架::g_变换手柄->f_get位置();
	步进 /= g记录初始步进;
	//步进 -= g记录初始步进;
	//步进 /= g投影比例.x;
	for (int32 i = 0; i < num; ++i) {
		vec3 dir = v[i] - 手柄位置;

		ob[i]->f_set位置(手柄位置 + dir * 步进, 0);
		ob[i]->f_set缩放(s[i] * 步进, 0);
	}

	

	f_OE_缩放后更新(g要变换的物体);
}

void f_控制手柄_局部缩放物体(E_轴向 轴向, float32 步进) {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();
	auto* g = g要变换的物体暂存全局坐标.data();

	vec3 手柄位置 = S_框架::g_变换手柄->f_get位置();
	步进 /= g记录初始步进;

	switch (S_框架::g_变换轴) {
	case E_轴向::e_X: {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - 手柄位置;

			dir.x *= 步进;
			ob[i]->f_set位置(手柄位置 + dir, 0);
			vec3 缩放步进  = s[i];
			缩放步进.x *= 步进;
			ob[i]->f_set缩放(缩放步进, 0);
		}
		break;
	}
	case E_轴向::e_Y: {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - 手柄位置;

			dir.y *= 步进;
			ob[i]->f_set位置(手柄位置 + dir, 0);
			vec3 缩放步进  = s[i];
			缩放步进.y *= 步进;
			ob[i]->f_set缩放(缩放步进, 0);
		}
		break;
	}
	case E_轴向::e_Z: {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - 手柄位置;

			dir.z *= 步进;
			ob[i]->f_set位置(手柄位置 + dir, 0);
			vec3 缩放步进  = s[i];
			缩放步进.z *= 步进;
			ob[i]->f_set缩放(缩放步进, 0);
		}
		break;
	}
	case E_轴向::e_XYZ: {
		for (int32 i = 0; i < num; ++i) {
			vec3 dir = v[i] - 手柄位置;

			ob[i]->f_set位置(手柄位置 + dir * 步进, 0);
			ob[i]->f_set缩放(s[i] * 步进, 0);
		}
		break;
	}
	default:
		break;
	}

	f_OE_缩放后更新(g要变换的物体);
}

void f_控制手柄_完成缩放物体() {
	g要变换的物体暂存缩放.clear();
	g要变换的物体暂存位置.clear();
	g要变换的物体.clear();

	f_global_变换手柄到物体中心();
	f_projectFile_设置文件保存状态(false);
}

void f_控制手柄_取消缩放物体() {
	uint32 num = g要变换的物体.size();
	auto* ob = g要变换的物体.data();
	auto* v = g要变换的物体暂存位置.data();
	auto* s = g要变换的物体暂存缩放.data();

	for (int32 i = 0; i < num; ++i) {
		ob[i]->f_set位置(v[i], 0);
		ob[i]->f_set缩放(s[i], 0);
	}

	f_控制手柄_完成缩放物体();
}







void f_视口控制_镜头视点移动到激活物体中心(S_摄像机* camera) {
	vec3 中心 = f_global_get激活物体中心点();
	/*auto obsNode = f_global_get激活可视物体节点();
	uint32 num = 0;

	if (num) {
		for (auto* node : obsNode) {
			auto* ob = node->f_get虚拟体();
			if (ob) {
				中心 = 中心 + ob->f_get位置();
				++num;
			}
		}
		中心 = 中心 / num;
	}*/

	
	if (S_节点数据::g_选中激活物体.size()) {
		f_set摄像机视点位置(camera, 中心);
	}
	else {
		f_set摄像机视点移动到偏移点(camera);
	}
	
}

/*void f_控制手柄_变换手柄开关(E_变换 变换, bool 打开) {
	switch (变换) {
	case E_变换::e_移动:
		f_变换手柄_移动手柄显示(true);

		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_轴线_移动, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_箭头X_移动, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_箭头Y_移动, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_箭头Z_移动, 打开);
		break;

	case E_变换::e_旋转:
		f_变换手柄_旋转手柄显示(true);

		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_万向_旋转, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_线圈X_旋转, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_线圈Y_旋转, 打开);
		f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_线圈Z_旋转, 打开);
		break;

	case E_变换::e_缩放:
		f_变换手柄_缩放手柄显示(true);
		break;
	default:
		break;
	}
}*/

void f_控制手柄_移动到选中物体中心() {
	S_框架::g_变换手柄->f_set位置(f_global_get激活物体中心点(), 0);

}

void f_控制手柄_轴线显示(E_轴向 轴向) {
	
	for (uint32 i = 0; i < 3; ++i) {
		if (轴向 & 1<<i) {
			auto Indirect = S_框架::g_变换手柄轴向线[i]->m_PickIndirect;
			Indirect.instanceCount = 1;
			f_surface_set间接绘制区间(f_ob_fromMesh(S_框架::g_变换手柄), Indirect, S_框架::g_变换手柄轴向线[i]->m_ID);
			//f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_x轴线, true);
		}
		else {
			f_surface_set间接绘制区间(f_ob_fromMesh(S_框架::g_变换手柄), S_框架::g_变换手柄轴向线[i]->m_PickIndirect, S_框架::g_变换手柄轴向线[i]->m_ID);
			//f_ob_set物体数据可视(S_框架::g_变换手柄_准备替换, DEF_视口手柄元素网格_x轴线, false);
		}
	}

}





void on_控制手柄切换(S_Props& prop) {
	auto* e = f_prop_Bool_1D(prop);
	for (uint8 i = 0; i < 3; ++i) {
		E_变换 变换方式 = E_变换(i + 1);
		//f_控制手柄_变换手柄开关(变换方式, e[i].m_Value);

		if (e[i].m_Value) {
			switch (变换方式) {
			case E_变换::e_移动: S_框架::g_变换方式 = E_变换::e_移动;
				f_变换手柄_移动手柄显示(true);
				break;
			case E_变换::e_旋转: S_框架::g_变换方式 = E_变换::e_旋转;
				f_变换手柄_旋转手柄显示(true);
				break;
			case E_变换::e_缩放: S_框架::g_变换方式 = E_变换::e_缩放;
				f_变换手柄_缩放手柄显示(true);
				break;
			}
		}
	}
}



